#include <gtest/gtest.h>

#include <mutex>
#include <thread>

using namespace std::chrono_literals;

// 演示 std::timed_mutex 的 try_lock_for 行为。
// holder 线程持有锁一段时间，另一个线程尝试超时获取。
TEST(TimedMutexTest, TryLockForBehavior) {
    std::timed_mutex tm;
    bool readyToRelease = false;

    // 持有者线程：先锁定，再在锁内睡眠 30ms，然后释放。
    std::thread holder([&] {
        std::lock_guard<std::timed_mutex> lock(tm);
        readyToRelease = true;
        std::this_thread::sleep_for(30ms);
    });

    // 确保 holder 已经获取锁。
    std::this_thread::sleep_for(5ms);
    EXPECT_TRUE(readyToRelease);

    // 由于锁未释放，try_lock_for 立即返回 false。
    EXPECT_FALSE(tm.try_lock_for(5ms));

    holder.join();

    // holder 结束后，再次尝试获取锁，这次应成功。
    EXPECT_TRUE(tm.try_lock_for(20ms));
    tm.unlock();
}

// 演示 try_lock_until：设定一个绝对时间点，若到时仍无法获得互斥锁，则超时失败。
TEST(TimedMutexTest, TryLockUntilBehavior) {
    std::timed_mutex tm;

    // 另一个线程持锁 15ms。
    std::thread holder([&] {
        std::lock_guard<std::timed_mutex> lock(tm);
        std::this_thread::sleep_for(15ms);
    });

    // 规划一个 10ms 后的截止时间点。
    auto deadline = std::chrono::steady_clock::now() + 10ms;

    // 在截止时间之前尝试获取锁，但持有者要 15ms 才释放，因此会超时失败。
    EXPECT_FALSE(tm.try_lock_until(deadline));

    holder.join();

    // 截止时间已过，锁释放后可以再次尝试，这次应成功。
    deadline = std::chrono::steady_clock::now() + 20ms;
    EXPECT_TRUE(tm.try_lock_until(deadline));
    tm.unlock();
}